Skip to content

Parse parameterized view calls with a database and non-literal arguments - #342

Merged
git-hulk merged 2 commits into
AfterShip:masterfrom
sharadgaur:parameterized-view-call-arguments
Nov 13, 2026
Merged

git-hulk merged 2 commits into
AfterShip:masterfrom
sharadgaur:parameterized-view-call-arguments

Conversation

@sharadgaur

Copy link
Copy Markdown
Contributor

Summary

A parameterized view, a CREATE VIEW whose query has {name:Type}
placeholders, is called like a table function: view(name = value). The
parser rejected two parts of that call.

  1. A database-qualified name, db.view(name = value). A qualified name
    followed by ( was always read as a plain table.
  2. An argument that is an array or a query parameter, for example
    ids = [1, 2], id = {id:UInt64} or ids = [{id:UInt64}]. A view
    that passes its own parameters to another parameterized view uses
    this form.

ClickHouse prints the qualified call as `db.view`(...) when it
formats a query. That form goes through the unqualified path and parses
once the arguments do.

Validation against ClickHouse

Checked with clickhouse local 26.2.1 using formatQuery, which parses
without needing the view to exist. The parser agrees with ClickHouse on
every row, and each formatted output was fed back to ClickHouse and
parses.

SQL (SELECT id FROM ...) ClickHouse Parser
db.v(a = 1) valid accepts
db.v(a = {x:UInt64}) valid accepts
db.v(a = {x:Array(UInt64)}, b = [{y:UInt64}], c = toDateTime64({z:String}, 3)) valid accepts
db.v(a = [1, 2], b = [], c = -1, d = 1 + 1, e = now()) valid accepts
`db.v`(a = {x:UInt64}, b = [1, 2]) valid accepts
v(a = {x:UInt64}, b = [1, 2]) valid accepts
db.v(a = {x:UInt64}) AS p, also on the right of a JOIN and in a subquery valid accepts
db.v(), db.v(1, 2) valid accepts
db.v(a = {x}) syntax error rejects
db.v(a = {'k': 1}), db.v(a = {}) syntax error rejects
db.v(a = [1, ), db.v(a = ), db.v(a = 1 syntax error rejects
db.v(a = 1)(b = 2) syntax error rejects
db.(a = 1), db.t (SELECT 1) syntax error rejects

A semantic check with a real view, also on 26.2.1:

CREATE VIEW d.pv AS SELECT id FROM d.t WHERE id >= {min_id:UInt64} AND id IN {ids:Array(UInt64)};
CREATE VIEW d.outer_v AS SELECT id FROM d.pv(min_id = {min_id:UInt64}, ids = {ids:Array(UInt64)});
SELECT groupArray(id) FROM d.outer_v(min_id = 3, ids = [2, 3]);   -- [3]

Changes

  • parseTableExpr builds a TableFunctionExpr for a qualified name
    followed by (. Name is the TableIdentifier in that case and stays
    an Ident for an unqualified call, so existing output does not change.
  • parseTableArgPrimaryExpr accepts [ as an array and { as a query
    parameter, reusing parseArrayParams and parseQueryParam. { is not
    read as a map literal here, because ClickHouse rejects {'k': 1}.

No AST type, visitor, walk or formatter change.

Not in this PR

  • FINAL after a table function call is still rejected with the
    existing error. ClickHouse parses db.v(a = 1) FINAL.
  • A three-part name, a.b.c(x = 1), is still rejected. ClickHouse parses
    it.
  • TableArgListExpr.End() returns the position of ), not the position
    after it. That is existing behaviour for every table function call.

Tests

  • testdata/query/select_from_parameterized_view.sql
  • Rejected forms added to TestParser_InvalidSyntax.
  • No existing golden file changes.

make test passes. golangci-lint v1.53.3 (the CI version) reports nothing.

A parameterized view is called like a table function. Two parts of that
call were rejected:

- a database-qualified name, db.view(name = value)
- an argument that is an array or a query parameter, such as
  ids = [1, 2] or id = {id:UInt64}

ClickHouse prints the qualified call as `db.view`(...) when it formats
a query. That form already parsed once the arguments did.
git-hulk
git-hulk previously approved these changes Nov 13, 2026
@git-hulk

Copy link
Copy Markdown
Member

@sharadgaur Can you resolve the conflict.

…w-call-arguments

# Conflicts:
#	parser/parser_test.go
@git-hulk
git-hulk merged commit 9dad6c2 into AfterShip:master Nov 13, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants